/* 
 * RemoteBusinessServiceImpl.java 02.10.2011
 *  
 *  
 * Candidate: Alessandra Otterbach
 * Prometric ID: Algisina1
 * Username: Algisina
 *  
 * Sun Certified Developer for Java 2 Platform, Standard Edition Programming 
 * Assignment (CX-310-252A)
 *  
 * This class is part of the Programming Assignment of the Sun Certified 
 * Developer for Java 2 Platform, Standard Edition certification program, must 
 * not be used out of this context and must be used exclusively by Sun 
 * Microsystems, Inc. 
 */
package suncertify.bs;

import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import suncertify.dao.EnumSearchCriteria;
import suncertify.dao.RoomRecord;
import suncertify.db.DB;
import suncertify.db.Data;
import suncertify.db.exc.RecordNotFoundException;
import suncertify.db.exc.SecurityException;
import suncertify.util.RoomConverter;
import suncertify.util.SearchCriteriaConverter;
import suncertify.util.StringUtils;

/**
 * @author Alessandra Otterbach
 * 
 */
public class RemoteBusinessServiceImpl implements RemoteBusinessService {

    private static final long serialVersionUID = 1L;

    private DB database = null;

    private static Logger logger = Logger.getLogger("suncertify.bs");

    public RemoteBusinessServiceImpl(String path) throws RemoteException {
	try {
	    database = Data.getInstance(path);
	} catch (RecordNotFoundException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see suncertify.bs.BusinessService#searchRoom(java.lang.String,
     * java.util.Map)
     */
    @Override
    public List<RoomRecord> searchRoom(
	    Map<EnumSearchCriteria, String> searchCriterias)
	    throws RecordNotFoundException, IOException, RemoteException {
	//logger.entering(this.getClass().getName(), "searchRoom");
	System.out.println("search remote");
	List<RoomRecord> allRooms = new ArrayList<RoomRecord>();

	int[] recNos = database.find(SearchCriteriaConverter
		.searchCriteriaAsArray(searchCriterias));

	for (int i = 0; i < recNos.length; i++) {
	    String[] recordValues = database.read(recNos[i]);
	    RoomRecord room = RoomConverter.arrayAsRoom(recordValues);
	    room.setId(recNos[i]);
	    allRooms.add(room);
	}

	// Filtering
	String nameCriteria = null;
	String locationCriteria = null;
	if (searchCriterias != null
		&& searchCriterias.get(EnumSearchCriteria.NAME) != null) {
	    nameCriteria = searchCriterias.get(EnumSearchCriteria.NAME);
	}
	if (searchCriterias != null
		&& searchCriterias.get(EnumSearchCriteria.LOCATION) != null) {
	    locationCriteria = searchCriterias.get(EnumSearchCriteria.LOCATION);
	}
	List<RoomRecord> toDelete = new ArrayList<RoomRecord>();
	for (int i = 0; i < allRooms.size(); i++) {

	    RoomRecord room = allRooms.get(i);

	    if (StringUtils.isNotEmpty(nameCriteria)
		    && StringUtils.isNotEmpty(locationCriteria)) {
		if (!(room.getName().equals(nameCriteria) && room.getLocation()
			.equals(locationCriteria))) {
		    toDelete.add(room);
		}
	    }
	}

	allRooms.removeAll(toDelete);
	//logger.exiting(this.getClass().getName(), "searchRoom");
	return allRooms;
    }

    /*
     * (non-Javadoc)
     * 
     * @see suncertify.bs.BusinessService#bookRoom(java.lang.String, int,
     * suncertify.dao.RoomRecord)
     */
    @Override
    public void bookRoom(int recNo, RoomRecord room)
	    throws RecordNotFoundException, SecurityException, IOException,
	    RemoteException {
	logger.entering(this.getClass().getName(), "bookRoom()");
	// Remember if you are doing lock/process/unlock within the context of a
	// single method call; from the Booking() method:
	//
	// Get a cookie (long) for your lock method
	// Lock with this cookie (put record number and this cookie in the
	// locking map)
	// Process using this cookie (compare this cookie with cookie in the
	// locking map)
	// Unlock using this cookie (compare this cookie with cookie in the
	// locking map)

	long lockCookie = database.lock(recNo);
	database.update(recNo, RoomConverter.roomAsArray(room), lockCookie);
	database.unlock(recNo, lockCookie);
	logger.exiting(this.getClass().getName(), "bookRoom()");
    }

}
